package BehaviorPattern.TemplateMethod;

/**
 * @author: Themberfue
 * @date: 2025/8/13 11:05
 * @description:
 */
// 1. 抽象类：定义饮品制作的模板
abstract class BeverageMaker {
    // 模板方法：定义算法骨架，声明为final防止子类修改
    public final void makeBeverage() {
        boilWater();         // 步骤1：煮水（公共步骤）
        brew();              // 步骤2：冲泡（子类实现）
        pourInCup();         // 步骤3：倒入杯中（公共步骤）

        // 钩子方法：是否添加调料（可选步骤）
        if (shouldAddCondiments()) {
            addCondiments(); // 步骤4：添加调料（子类实现）
        }

        System.out.println("饮品制作完成！");
        System.out.println("---------------------");
    }

    // 抽象方法：冲泡（子类实现）
    protected abstract void brew();

    // 抽象方法：添加调料（子类实现）
    protected abstract void addCondiments();

    // 具体方法：煮水（公共步骤）
    private void boilWater() {
        System.out.println("煮水至沸腾");
    }

    // 具体方法：倒入杯中（公共步骤）
    private void pourInCup() {
        System.out.println("将饮品倒入杯中");
    }

    // 钩子方法：默认添加调料，子类可重写
    protected boolean shouldAddCondiments() {
        return true;
    }
}

// 2. 具体子类：咖啡
class Coffee extends BeverageMaker {
    @Override
    protected void brew() {
        System.out.println("用沸水冲泡咖啡粉");
    }

    @Override
    protected void addCondiments() {
        System.out.println("添加牛奶和糖");
    }

    // 重写钩子方法：询问用户是否添加调料
    @Override
    protected boolean shouldAddCondiments() {
        // 实际应用中可以在这里添加用户输入逻辑
        return true; // 简化处理，默认添加
    }
}

// 3. 具体子类：茶
class Tea extends BeverageMaker {
    @Override
    protected void brew() {
        System.out.println("用沸水浸泡茶叶");
    }

    @Override
    protected void addCondiments() {
        System.out.println("添加柠檬");
    }

    // 可以选择不重写钩子方法，使用父类默认实现
}

// 4. 具体子类：黑咖啡（不添加调料）
class BlackCoffee extends BeverageMaker {
    @Override
    protected void brew() {
        System.out.println("用沸水冲泡浓缩咖啡粉");
    }

    @Override
    protected void addCondiments() {
        // 空实现，因为黑咖啡不加调料
    }

    // 重写钩子方法：不添加调料
    @Override
    protected boolean shouldAddCondiments() {
        return false;
    }
}

// 5. 客户端代码
public class TemplateMethodExample {
    public static void main(String[] args) {
        System.out.println("=== 制作咖啡 ===");
        BeverageMaker coffee = new Coffee();
        coffee.makeBeverage();

        System.out.println("=== 制作茶 ===");
        BeverageMaker tea = new Tea();
        tea.makeBeverage();

        System.out.println("=== 制作黑咖啡 ===");
        BeverageMaker blackCoffee = new BlackCoffee();
        blackCoffee.makeBeverage();
    }
}

